package com.yuma.tingshu.search.service.impl;

import com.yuma.tingshu.album.client.AlbumInfoFeignClient;
import com.yuma.tingshu.album.client.CategoryFeignClient;
import com.yuma.tingshu.common.result.Result;
import com.yuma.tingshu.model.album.AlbumInfo;
import com.yuma.tingshu.model.album.BaseCategoryView;
import com.yuma.tingshu.model.user.UserInfo;
import com.yuma.tingshu.search.service.ItemService;
import com.yuma.tingshu.user.client.UserInfoFeignClient;
import com.yuma.tingshu.vo.album.AlbumStatVo;
import com.yuma.tingshu.vo.search.AlbumItemVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class ItemServiceImpl implements ItemService {

    @Resource
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Resource
    private CategoryFeignClient categoryFeignClient;

    @Resource
    private UserInfoFeignClient userInfoFeignClient;

    @Resource(name = "searchThreadPoolConfig")
    private ExecutorService executorService;

    public AlbumItemVo loadAlbumData1(Long albumId) {

        AlbumItemVo albumItemVo = new AlbumItemVo();

        // 1.根据专辑id查询专辑
        Result<AlbumInfo> albumInfoResult = this.albumInfoFeignClient.getAlbumInfo(albumId);
        Assert.notNull(albumInfoResult, "专辑详情页，获取专辑信息失败！");
        AlbumInfo albumInfo = albumInfoResult.getData();
        Assert.notNull(albumInfo, "专辑详情页，对应的专辑不存在!" + albumId);
        albumItemVo.setAlbumInfo(albumInfo);

        // 2.根据专辑id查询统计信息
        Result<AlbumStatVo> albumStatResult = this.albumInfoFeignClient.getAlbumStatByAlbumId(albumId);
        Assert.notNull(albumStatResult, "专辑详情页，获取专辑统计信息失败");
        AlbumStatVo albumStatVo = albumStatResult.getData();
        albumItemVo.setAlbumStatVo(albumStatVo);

        // 3.根据三级分类id查询一二三级分类
        Result<BaseCategoryView> baseCategoryViewResult = this.categoryFeignClient.getBaseCategoryViewByCategory3Id(albumInfo.getCategory3Id());
        Assert.notNull(baseCategoryViewResult, "专辑详情页，获取三级分类信息失败");
        BaseCategoryView baseCategoryView = baseCategoryViewResult.getData();
        albumItemVo.setBaseCategoryView(baseCategoryView);

        // 4.获取主播信息
        Result<UserInfo> userInfoResult = this.userInfoFeignClient.getUserById(albumInfo.getUserId());
        Assert.notNull(userInfoResult, "专辑详情页，获取专辑主播信息失败");
        UserInfo userInfo = userInfoResult.getData();
        albumItemVo.setAnnouncer(userInfo);
        return albumItemVo;
    }

    /**
     *  [主线程] Tomcat-exec-3
     *     │
     *     ├── 处理 HTTP 请求
     *     ├── 初始化 RequestContextHolder
     *     ├── 调用 loadAlbumData()
     *     └── 提交异步任务 → executorService.submit(task)
     *             │
     *             ▼
     * [子线程] ContextAware-1 ← TaskDecorator 在这里注入上下文！
     *     │
     *     ├── RequestContextHolder.setRequestAttributes(从主线程捕获的context)
     *     ├── 执行你的 Lambda → 调用 Feign
     *     │     └── FeignInterceptor 能拿到 token！
     *     └── finally: RequestContextHolder.resetRequestAttributes()
     */

    @Override
    public AlbumItemVo loadAlbumData(Long albumId) {

        AlbumItemVo albumItemVo = new AlbumItemVo();

        // 1.根据专辑id查询专辑
        CompletableFuture<AlbumInfo> future = CompletableFuture.supplyAsync(() -> {
            Result<AlbumInfo> albumInfoResult = this.albumInfoFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult, "专辑详情页，获取专辑信息失败！");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo, "专辑详情页，对应的专辑不存在!" + albumId);
            albumItemVo.setAlbumInfo(albumInfo);
            return albumInfo;
        }, executorService);

        // 2.根据专辑id查询统计信息
        CompletableFuture<Void> statFuture = CompletableFuture.runAsync(() -> {
            Result<AlbumStatVo> albumStatResult = this.albumInfoFeignClient.getAlbumStatByAlbumId(albumId);
            Assert.notNull(albumStatResult, "专辑详情页，获取专辑统计信息失败");
            AlbumStatVo albumStatVo = albumStatResult.getData();
            albumItemVo.setAlbumStatVo(albumStatVo);
        }, executorService);

        // 3.根据三级分类id查询一二三级分类
        CompletableFuture<Void> categoryFuture = future.thenAcceptAsync((albumInfo) -> {
            Result<BaseCategoryView> baseCategoryViewResult = this.categoryFeignClient.getBaseCategoryViewByCategory3Id(albumInfo.getCategory3Id());
            Assert.notNull(baseCategoryViewResult, "专辑详情页，获取三级分类信息失败");
            BaseCategoryView baseCategoryView = baseCategoryViewResult.getData();
            albumItemVo.setBaseCategoryView(baseCategoryView);
        }, executorService);

        // 4.获取主播信息
        CompletableFuture<Void> userFuture = future.thenAcceptAsync((albumInfo) -> {
            Result<UserInfo> userInfoResult = this.userInfoFeignClient.getUserById(albumInfo.getUserId());
            Assert.notNull(userInfoResult, "专辑详情页，获取专辑主播信息失败");
            UserInfo userInfo = userInfoResult.getData();
            albumItemVo.setAnnouncer(userInfo);
        }, executorService);

        CompletableFuture.allOf(categoryFuture, statFuture, userFuture).join();// 等待所有任务完成
        return albumItemVo;
    }
}
